home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_1 / executive_v1.00 / sysinfo.lzx / examples / uptime / uptime.c < prev   
C/C++ Source or Header  |  1990-07-29  |  7KB  |  352 lines

  1. /*
  2.  * Uptime
  3.  *
  4.  * This file is public domain.
  5.  *
  6.  * Author: Petri Nordlund <petrin@mits.mdata.fi>
  7.  *
  8.  * $Id: uptime.c 1.4 1995/08/24 10:52:04 petrin Exp petrin $
  9.  *
  10.  */
  11.  
  12. /*
  13.  * This is a fairly complete uptime-program. The sourcecode comes from Executive
  14.  * uptime-client, it's just modified to support sysinfo.library. This program
  15.  * can be compiled for multiuser.library support to show the number of users
  16.  * currently logged in. This requires multiuser.library include-files and
  17.  * a stub-library if you are using GCC. See GCC:geninline/README.glue for
  18.  * information about how to generate the stub-library.
  19.  */
  20.  
  21. #include "defs.h"
  22. #include <proto/sysinfo.h>
  23. #include <libraries/sysinfo.h>
  24.  
  25. /* PROTOTYPES */
  26. #ifdef USE_MULTIUSER
  27. static void AddUser(ULONG user, UWORD *uids, ULONG *nusers);
  28. ULONG CountTasks(void);
  29. #endif
  30. static void MyExit(void);
  31. static void GetTime(void);
  32. static void Users(void);
  33. static void LoadAverages(void);
  34. static void Uptime(void);
  35.  
  36.  
  37. /* EXTERNAL VARIABLES */
  38. extern struct ExecBase *SysBase;
  39.  
  40.  
  41. /* VARIABLES */
  42. #ifdef USE_MULTIUSER
  43. struct muBase *muBase = NULL;
  44. #endif
  45. struct sysinfo *si = NULL;
  46. struct Library *SysinfoBase = NULL;
  47.  
  48.  
  49. int
  50. main(int argc, char **argv)
  51. {
  52.     /* MyExit will be called when we exit */
  53.     atexit(MyExit);
  54.  
  55.     if(!(SysinfoBase = OpenLibrary(SYSINFONAME, SYSINFOVERSION)))
  56.     {
  57.         puts("Can't open sysinfo.library.");
  58.         exit(RETURN_FAIL);
  59.     }
  60.  
  61.     /* Initialize sysinfo.library, this will make the connection to the
  62.      * server-process and allocate the sysinfo-structure. */
  63.     if(!(si = InitSysinfo()))
  64.     {
  65.         puts("Couldn't initialize sysinfo.");
  66.         exit(RETURN_FAIL);
  67.     }
  68.  
  69. #ifdef USE_MULTIUSER
  70.     /* If this fails, we'll just output `1 user' */
  71.     muBase = (struct muBase *) OpenLibrary(MULTIUSERNAME,MULTIUSERVERSION);
  72. #endif
  73.  
  74.     GetTime();
  75.     printf(", ");
  76.     Uptime();
  77.     printf(", ");
  78.     Users();
  79.     printf(", ");
  80.     LoadAverages();
  81.     printf("\n");
  82.  
  83.     return(RETURN_OK);
  84. }
  85.  
  86.  
  87. /*
  88.  * Exit. Free everything.
  89.  */
  90. static void
  91. MyExit(void)
  92. {
  93. #ifdef USE_MULTIUSER
  94.     if(muBase)
  95.         CloseLibrary((struct Library *) muBase);
  96. #endif
  97.  
  98.     /* Free sysinfo.library */
  99.     if(si)
  100.         FreeSysinfo(si);
  101.  
  102.     if(SysinfoBase)
  103.         CloseLibrary(SysinfoBase);
  104. }
  105.  
  106.  
  107. /*
  108.  * Print system time
  109.  */
  110. static void
  111. GetTime(void)
  112. {
  113.     struct DateTime dtime;
  114.     char timestr[LEN_DATSTRING+1];
  115.  
  116.     DateStamp(&dtime.dat_Stamp);
  117.  
  118.     dtime.dat_Format = FORMAT_DOS;
  119.     dtime.dat_Flags = 0;
  120.     dtime.dat_StrDay = NULL;
  121.     dtime.dat_StrDate = NULL;
  122.     dtime.dat_StrTime = timestr;
  123.  
  124.     DateToStr(&dtime);
  125.  
  126.     printf(timestr);
  127. }
  128.  
  129.  
  130. /*
  131.  * Print number of users (from Multiuser if available)
  132.  */
  133. static void
  134. Users(void)
  135. {
  136.     ULONG nusers = 1;
  137.  
  138. #ifdef USE_MULTIUSER
  139.     if(muBase)
  140.     {
  141.         ULONG numtasks;
  142.         UWORD *uids;
  143.  
  144.         Forbid();
  145.  
  146.         /* Count the number of tasks currently in system */
  147.         numtasks = CountTasks();
  148.  
  149.         /* Allocate memory for each task */
  150.         if(uids=AllocVec(numtasks*sizeof(UWORD),MEMF_CLEAR|MEMF_PUBLIC))
  151.         {
  152.             struct Task *task;
  153.  
  154.             /* Find out how many different uids there are */
  155.  
  156.             nusers = 0;
  157.             AddUser(muGetTaskOwner(FindTask(NULL)), uids, &nusers);
  158.             for(task = (struct Task *)SysBase->TaskReady.lh_Head;
  159.                 task->tc_Node.ln_Succ;
  160.                 task = (struct Task *)task->tc_Node.ln_Succ)
  161.                 AddUser(muGetTaskOwner(task), uids, &nusers);
  162.             for(task = (struct Task *)SysBase->TaskWait.lh_Head;
  163.                 task->tc_Node.ln_Succ;
  164.                 task = (struct Task *)task->tc_Node.ln_Succ)
  165.                 AddUser(muGetTaskOwner(task), uids, &nusers);
  166.             FreeVec(uids);
  167.         }
  168.  
  169.         Permit();
  170.     }
  171. #endif
  172.  
  173.     if((nusers>1) || (nusers==0))
  174.         printf("%d users", nusers);
  175.     else
  176.         printf("%d user",nusers);
  177. }
  178.  
  179.  
  180. #ifdef USE_MULTIUSER
  181. static void
  182. AddUser(ULONG user, UWORD *uids, ULONG *nusers)
  183. {
  184.     UWORD uid;
  185.     BOOL found = FALSE;
  186.     ULONG i;
  187.  
  188.     if(user)
  189.     {
  190.         uid = user>>16;
  191.         for(i=0; !found && (i<*nusers); i++)
  192.             found = (uids[i] == uid);
  193.         if(!found)
  194.             uids[(*nusers)++] = uid;
  195.     }
  196. }
  197.  
  198. static ULONG
  199. CountTasks(void)
  200. {
  201.     ULONG i = 1;
  202.     struct Task *task;
  203.  
  204.     for (task = (struct Task *)SysBase->TaskReady.lh_Head;
  205.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  206.           i++;
  207.     for (task = (struct Task *)SysBase->TaskWait.lh_Head;
  208.           task->tc_Node.ln_Succ; task = (struct Task *)task->tc_Node.ln_Succ)
  209.           i++;
  210.     return(i);
  211. }
  212. #endif
  213.  
  214.  
  215. /*
  216.  * Print uptime. We use RAM:-disk creation time.
  217.  */
  218. static void
  219. Uptime(void)
  220. {
  221.     LONG boottime;
  222.     LONG currenttime;
  223.     struct DateTime dtime;
  224.     BPTR lock;
  225.     struct InfoData *infodata;
  226.     struct DeviceList *ramdevice;
  227.  
  228. /*
  229.  * InfoData-structure must be long word aligned. By allocating it this way,
  230.  * we can make sure it is aligned properly. GCC has a bug in it's aligned-
  231.  * attribute <sigh> so it's not possible to just use: struct InfoData infodata.
  232.  */
  233.  
  234.     if(!(infodata=AllocMem(sizeof(struct InfoData),MEMF_ANY)))
  235.         return;
  236.  
  237.     if(lock = Lock("RAM:", SHARED_LOCK))
  238.     {
  239.         if((Info(lock, infodata)) == DOSTRUE)
  240.         {
  241.             ramdevice = BADDR(infodata->id_VolumeNode);
  242.  
  243.             boottime =  SMult32(ramdevice->dl_VolumeDate.ds_Days, 86400) +
  244.                         SMult32(ramdevice->dl_VolumeDate.ds_Minute, 60) +
  245.                         SDivMod32(ramdevice->dl_VolumeDate.ds_Tick, TICKS_PER_SECOND);
  246.  
  247.             DateStamp(&dtime.dat_Stamp);
  248.  
  249.             currenttime =     SMult32(dtime.dat_Stamp.ds_Days, 86400) +
  250.                             SMult32(dtime.dat_Stamp.ds_Minute, 60) +
  251.                             SDivMod32(dtime.dat_Stamp.ds_Tick, TICKS_PER_SECOND);
  252.  
  253.             currenttime -= boottime;
  254.  
  255.             if(currenttime > 0)
  256.             {
  257.                 ULONG days, hrs, mins, hrs_tmp;
  258.  
  259.                 /* Calculate days, hours and minutes */
  260.                 days = currenttime/86400;
  261.                 hrs_tmp = hrs = currenttime%86400;
  262.                 hrs = hrs/3600;
  263.                 mins = (hrs_tmp%3600) / 60;
  264.  
  265.                 if(days || hrs || mins)
  266.                     printf("up ");
  267.  
  268.                 if(days > 0)
  269.                 {
  270.                     if(days>1)
  271.                         printf("%d days ", days);
  272.                     else
  273.                         printf("%d day ", days);
  274.                 }
  275.                 if(hrs > 0)
  276.                     printf("%d:%02d", hrs, mins);
  277.                 else
  278.                 {
  279.                     if((mins>1) || (mins==0))
  280.                         printf("%d mins", mins);
  281.                     else
  282.                         printf("%d min", mins);
  283.                 }
  284.             }
  285.         }
  286.         UnLock(lock);
  287.     }
  288.  
  289.     FreeMem(infodata, sizeof(struct InfoData));
  290. }
  291.  
  292.  
  293. /*
  294.  * Print load averages
  295.  */
  296. static void
  297. LoadAverages(void)
  298. {
  299.     struct loadaverage load;    /* This will be filled by GetLoadAverage() */
  300.  
  301.     GetLoadAverage(si, &load);    /* Ask sysinfo.library for current load averages */
  302.  
  303.     printf("load:");
  304.  
  305.     switch(si->loadavg_type)
  306.     {
  307.         case LOADAVG_FIXEDPNT:
  308.  
  309.             /* Convert fixed point values to floating point values */
  310.  
  311.             if(si->loadavg_time1)
  312.                 printf(" %.2f",(float) load.loadaverage.lavg_fixed.load1 / (float) si->fscale);
  313.             else
  314.                 printf(" N/A");
  315.  
  316.             if(si->loadavg_time2)
  317.                 printf(" %.2f",(float) load.loadaverage.lavg_fixed.load2 / (float) si->fscale);
  318.             else
  319.                 printf(" N/A");
  320.  
  321.             if(si->loadavg_time3)
  322.                 printf(" %.2f",(float) load.loadaverage.lavg_fixed.load3 / (float) si->fscale);
  323.             else
  324.                 printf(" N/A");
  325.  
  326.             break;
  327.         case LOADAVG_FLOAT:
  328.  
  329.             /* Load averages are already in floating point format */
  330.  
  331.             if(si->loadavg_time1)
  332.                 printf(" %.2f",load.loadaverage.lavg_float.load1);
  333.             else
  334.                 printf(" N/A");
  335.  
  336.             if(si->loadavg_time2)
  337.                 printf(" %.2f",load.loadaverage.lavg_float.load2);
  338.             else
  339.                 printf(" N/A");
  340.  
  341.             if(si->loadavg_time3)
  342.                 printf(" %.2f",load.loadaverage.lavg_float.load3);
  343.             else
  344.                 printf(" N/A");
  345.  
  346.             break;
  347.         default:
  348.             /* Load average is not supported */
  349.             printf("-");
  350.     }
  351. }
  352.